//
//-------------------------------------------------------------------------
//                                                               
//                                                               
//    QuickBurro Middleware Application Development Package for Delphi VCL      
//                                                               
//    Version 4.38                                              
//    Update Date: 2015.2.3.                                    
//    Author: Jopher(W.G.Z.)                                     
//    QQ: 779545524  
//    QQ groups: 79114999,18594635       
//    Email: Jopher@189.cn  
//    Homepage: http://www.quickburro.com/               
//                                                               
//    Copyright(C) Jopher Software Studio,2006-2014. All rights reserved   
//                                                               
//                                                               
//-------------------------------------------------------------------------
//
Unit QBRsa;

Interface

Uses
   {$IF CompilerVersion>=23.0}Winapi.Windows{$ELSE}Windows{$IFEND},
   {$IF CompilerVersion>=23.0}System.SysUtils{$ELSE}SysUtils{$IFEND},
   {$IF CompilerVersion>=23.0}Vcl.Controls{$ELSE}Controls{$IFEND},
   {$IFDEF UNICODE}
   {$IF CompilerVersion>=23.0}System.AnsiStrings{$ELSE}AnsiStrings{$IFEND},
   {$ENDIF}
   GreatInt;

   Procedure _RSAEncrypt(P: AnsiString; Var exp, modb: TFGInt; Var E: AnsiString);
   Procedure _RSADecrypt(E: AnsiString; Var exp, modb, d_p, d_q, p, q: TFGInt; Var D: AnsiString);
   Procedure RSASign(M: AnsiString; Var d, n, dp, dq, p, q: TFGInt; Var S: AnsiString);
   Procedure RSAVerify(M, S: AnsiString; Var e, n: TFGInt; Var valid : boolean);
   function RsaEncrypt(SourceStr: AnsiString; ExpStr: AnsiString; ModbStr: AnsiString): AnsiString;
   function RsaDecrypt(SourceStr: AnsiString; ExpStr: AnsiString; ModbStr: AnsiString): AnsiString;

Implementation

{$H+}

Procedure _RSAEncrypt(P: AnsiString; Var exp, modb: TFGInt; Var E: AnsiString);
Var
   i, j, modbits : longint;
   PGInt, temp, zero : TFGInt;
   tempstr1, tempstr2, tempstr3: AnsiString;
Begin
   Base2StringToFGInt('0', zero);
   FGIntToBase2String(modb, tempstr1);
   modbits := length(tempstr1);
   convertBase256to2(P, tempstr1);
   tempstr1 := '111' + tempstr1;
   j := modbits - 1;
   While (length(tempstr1) Mod j) <> 0 Do
      tempstr1 := '0' + tempstr1;
   j := length(tempstr1) Div (modbits - 1);
   tempstr2 := '';
   For i := 1 To j Do
      Begin
         tempstr3 := copy(tempstr1, 1, modbits - 1);
         While (copy(tempstr3, 1, 1) = '0') And (length(tempstr3) > 1) Do
            delete(tempstr3, 1, 1);
         Base2StringToFGInt(tempstr3, PGInt);
         delete(tempstr1, 1, modbits - 1);
         If tempstr3 = '0' Then
            FGIntCopy(zero, temp)
         Else
            FGIntMontgomeryModExp(PGInt, exp, modb, temp);
         FGIntDestroy(PGInt);
         tempstr3 := '';
         FGIntToBase2String(temp, tempstr3);
         While (length(tempstr3) Mod modbits) <> 0 Do
            tempstr3 := '0' + tempstr3;
         tempstr2 := tempstr2 + tempstr3;
         FGIntdestroy(temp);
      End;
   While (tempstr2[1] = '0') And (length(tempstr2) > 1) Do
      delete(tempstr2, 1, 1);
   ConvertBase2To256(tempstr2, E);
   FGIntDestroy(zero);
End;

Procedure _RSADecrypt(E: AnsiString; Var exp, modb, d_p, d_q, p, q: TFGInt; Var D: AnsiString);
Var
   i, j, modbits: longint;
   EGInt, temp, temp1, temp2, temp3, ppinvq, qqinvp, zero: TFGInt;
   tempstr1, tempstr2, tempstr3: AnsiString;
Begin
   Base2StringToFGInt('0', zero);
   FGIntToBase2String(modb, tempstr1);
   modbits := length(tempstr1);
   convertBase256to2(E, tempstr1);
   While copy(tempstr1, 1, 1) = '0' Do
      delete(tempstr1, 1, 1);
   While (length(tempstr1) Mod modbits) <> 0 Do
      tempstr1 := '0' + tempstr1;
   If exp.Number = Nil Then
      Begin
         FGIntModInv(q, p, temp1);
         FGIntMul(q, temp1, qqinvp);
         FGIntDestroy(temp1);
         FGIntModInv(p, q, temp1);
         FGIntMul(p, temp1, ppinvq);
         FGIntDestroy(temp1);
      End;
   j := length(tempstr1) Div modbits;
   tempstr2 := '';
   For i := 1 To j Do
      Begin
         tempstr3 := copy(tempstr1, 1, modbits);
         While (copy(tempstr3, 1, 1) = '0') And (length(tempstr3) > 1) Do
            delete(tempstr3, 1, 1);
         Base2StringToFGInt(tempstr3, EGInt);
         delete(tempstr1, 1, modbits);
         If tempstr3 = '0' Then
            FGIntCopy(zero, temp)
         Else
            Begin
               If exp.Number <> Nil Then
                  FGIntMontgomeryModExp(EGInt, exp, modb, temp)
               Else
                  Begin
                     FGIntMontgomeryModExp(EGInt, d_p, p, temp1);
                     FGIntMul(temp1, qqinvp, temp3);
                     FGIntCopy(temp3, temp1);
                     FGIntMontgomeryModExp(EGInt, d_q, q, temp2);
                     FGIntMul(temp2, ppinvq, temp3);
                     FGIntCopy(temp3, temp2);
                     FGIntAddMod(temp1, temp2, modb, temp);
                     FGIntDestroy(temp1);
                     FGIntDestroy(temp2);
                  End;
            End;
         FGIntDestroy(EGInt);
         tempstr3 := '';
         FGIntToBase2String(temp, tempstr3);
         While (length(tempstr3) Mod (modbits - 1)) <> 0 Do
            tempstr3 := '0' + tempstr3;
         tempstr2 := tempstr2 + tempstr3;
         FGIntdestroy(temp);
      End;

   If exp.Number = Nil Then
      Begin
         FGIntDestroy(ppinvq);
         FGIntDestroy(qqinvp);
      End;
   While (Not (copy(tempstr2, 1, 3) = '111')) And (length(tempstr2) > 3) Do
      delete(tempstr2, 1, 1);
   delete(tempstr2, 1, 3);
   ConvertBase2To256(tempstr2, D);
   FGIntDestroy(zero);
End;

Procedure RSASign(M: AnsiString; Var d, n, dp, dq, p, q: TFGInt; Var S: AnsiString);
Var
   MGInt, SGInt, temp, temp1, temp2, temp3, ppinvq, qqinvp : TFGInt;
Begin
   Base256StringToFGInt(M, MGInt);
   If d.Number <> Nil Then
      FGIntMontgomeryModExp(MGInt, d, n, SGInt)
   Else
      Begin
         FGIntModInv(p, q, temp);
         FGIntMul(p, temp, ppinvq);
         FGIntDestroy(temp);
         FGIntModInv(q, p, temp);
         FGIntMul(q, temp, qqinvp);
         FGIntDestroy(temp);
         FGIntMontgomeryModExp(MGInt, dp, p, temp1);
         FGIntMul(temp1, qqinvp, temp2);
         FGIntCopy(temp2, temp1);
         FGIntMontgomeryModExp(MGInt, dq, q, temp2);
         FGIntMul(temp2, ppinvq, temp3);
         FGIntCopy(temp3, temp2);
         FGIntAddMod(temp1, temp2, n, SGInt);
         FGIntDestroy(temp1);
         FGIntDestroy(temp2);
         FGIntDestroy(ppinvq);
         FGIntDestroy(qqinvp);
      End;
   FGIntToBase256String(SGInt, S);
   FGIntDestroy(MGInt);
   FGIntDestroy(SGInt);
End;

Procedure RSAVerify(M, S: AnsiString; Var e, n: TFGInt; Var valid: boolean);
Var
   MGInt, SGInt, temp: TFGInt;
Begin
   Base256StringToFGInt(S, SGInt);
   Base256StringToFGInt(M, MGInt);
   FGIntMod(MGInt, n, temp);
   FGIntCopy(temp, MGInt);
   FGIntMontgomeryModExp(SGInt, e, n, temp);
   FGIntCopy(temp, SGInt);
   valid := (FGIntCompareAbs(SGInt, MGInt) = Eq);
   FGIntDestroy(SGInt);
   FGIntDestroy(MGInt);
End;

function RsaEncrypt(SourceStr: AnsiString; ExpStr: AnsiString; ModbStr: AnsiString): AnsiString;
var
   tmpstr: ansistring;
   e,n: tfgint;
begin
   Base10StringToFGInt(expstr, e);
   Base10StringToFGInt(modbstr, n);
   _RSAEncrypt(SourceStr, e, n, tmpstr);
   ConvertBase256to64(tmpstr,result);
   FGIntDestroy(e);
   FGIntDestroy(n);
end;

function RsaDecrypt(SourceStr: AnsiString; ExpStr: AnsiString; ModbStr: AnsiString): AnsiString;
var
   tmpstr: ansistring;
   d,n,nilgint: tfgint;
begin
   ConvertBase64to256(SourceStr,tmpstr);
   Base10StringToFGInt(ExpStr, d);
   Base10StringToFGInt(ModbStr, n);
   _RSADecrypt(tmpstr, d, n, Nilgint, Nilgint, Nilgint, Nilgint, result);
   FGIntDestroy(d);
   FGIntDestroy(n);
   FGIntDestroy(nilgint);
end;

End.

